package com.nicefact.mailmonitor.workflow.impl.task;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.logging.Logger;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.google.appengine.api.blobstore.BlobInfo;
import com.google.appengine.api.blobstore.BlobInfoFactory;
import com.google.appengine.api.blobstore.BlobKey;
import com.google.appengine.api.blobstore.BlobstoreService;
import com.google.appengine.api.blobstore.BlobstoreServiceFactory;
import com.nicefact.mailmonitor.core.AppException;
import com.nicefact.mailmonitor.dao.MailReportDao;
import com.nicefact.mailmonitor.entity.LogMessage;
import com.nicefact.mailmonitor.service.LogMessageService;
import com.nicefact.mailmonitor.util.CSVFileReader;
import com.nicefact.mailmonitor.util.UserUtil;
import com.nicefact.mailmonitor.vo.MailReport;
import com.nicefact.mailmonitor.workflow.AbstractWorkflowTask;
import com.nicefact.mailmonitor.workflow.WorkflowContext;
import com.nicefact.mailmonitor.workflow.WorkflowExecutionException;
import com.nicefact.mailmonitor.workflow.WorkflowInfo;
import com.nicefact.mailmonitor.workflow.entity.Workflow;
import com.nicefact.mailmonitor.workflow.impl.context.ReadCSVContext;
import com.nicefact.mailmonitor.workflow.impl.context.ReportGenerationContext;
import com.nicefact.mailmonitor.workflow.impl.processor.WorkflowStatusType;
import com.nicefact.mailmonitor.workflow.service.WorkflowService;

public class ReadCSVTask extends AbstractWorkflowTask {

	protected final Logger logger = Logger.getLogger(getClass().getName());

	@Autowired
	private LogMessageService logMessageService;

	@Autowired
	WorkflowService workflowService;

	@Autowired
	MailReportDao mailReportDao;

	public static int runs = 0;

	@Override
	public WorkflowContext execute(WorkflowContext context)
			throws WorkflowExecutionException {
		ReadCSVContext readCSVContext = (ReadCSVContext) context;

		String adminEmail = readCSVContext.getAdminEmail();
		LogMessage logMessage = new LogMessage();
		logMessage.setCreatedBy(adminEmail);
		try {
			BlobKey csvBlobKey = readCSVContext.getBlobKey();
			Date fromDate = adjustTimeToPST(readCSVContext.getFromDate());
			Date toDate =adjustTimeToPST(readCSVContext.getToDate());
			List<String> users = getUsersFromCSV(csvBlobKey);
			ReportGenerationTask.initTask();
			List<MailReport> reports = mailReportDao.getAllForUser(adminEmail);
			if (reports != null && !reports.isEmpty()) {
				mailReportDao.removeAll(reports);
			}
			for (String user : users) {
				triggerReportGenerationTask(adminEmail, user, fromDate,toDate, users.size());
			}
			logMessage.setMessage("User list is under processing");
		} catch (Exception e) {
			logMessage.setMessage("User list import Failed");
			System.out.println("error  : " + e.getMessage());
		}
		logMessageService.save(logMessage);
		System.out.println("file read task finished. No. of runs :" + ++runs);

		return context;
	}

	void triggerReportGenerationTask(String adminEmail, String userEmail,
			Date from, Date toDate, Integer totalAccounts) throws AppException {

		ReportGenerationContext context = new ReportGenerationContext();
		context.setAdminEmail(adminEmail);
		context.setFromDate(from);
		context.setToDate(toDate);
		context.setUserEmail(userEmail);
		context.setTotalAccounts(totalAccounts);
		WorkflowInfo workflowInfo = new WorkflowInfo(
				"ReportGenerationTaskProcessor");
		workflowInfo.setIsNewWorkflow(true);

		Workflow workflow = new Workflow();
		workflow.setContext(context);
		workflow.setWorkflowName(workflowInfo.getWorkflowName());
		workflow.setWorkflowInstanceId(workflowInfo.getWorkflowInstance());
		workflow.setWorkflowStatus(WorkflowStatusType.QUEUED.toString());
		workflowService.createWorkflow(workflow);
		context.setWorkflowInfo(workflowInfo);
		workflowService.triggerWorkflow(workflow);
	}

	Date adjustTimeToPST(Date date){
		/*Date newDate = null;
		if (date!=null) {
			Calendar cal = new GregorianCalendar();
			cal.setTime(date);
			cal.add(Calendar.HOUR, 8);
			newDate = cal.getTime();
		}
		return newDate;*/
		return date;
	}
	private List<String> getUsersFromCSV(BlobKey csvBlobKey) {
		List<String> mailIds = null;
		BlobstoreService blobstoreService = BlobstoreServiceFactory
				.getBlobstoreService();
		try {
			BlobInfo blobInfo = new BlobInfoFactory().loadBlobInfo(csvBlobKey);
			byte[] data = blobstoreService.fetchData(csvBlobKey, 0,
					blobInfo.getSize());
			InputStream stream = new ByteArrayInputStream(data);
			CSVFileReader x = new CSVFileReader(stream);
			x.ReadFile();
			mailIds = createUsersList(x.getStoreValuesList());
			stream.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				blobstoreService.delete(csvBlobKey);
			} catch (Exception e2) {
				System.err.println("Could not delete file from blob store");
			}
		}
		return mailIds;
	}

	private List<String> createUsersList(
			ArrayList<ArrayList<String>> storeValuesList) {
		List<String> mailIds = new ArrayList<String>();
		for (int i = 1; i < storeValuesList.size(); i++) {
			ArrayList<String> row = storeValuesList.get(i);
			String mailId = row.get(0);
			if (!StringUtils.isBlank(mailId) && UserUtil.isValidEmail(mailId)) {
				mailIds.add(mailId.trim());
			}
		}
		return mailIds;
	}

}
